home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / gnu / gnulib / sipp / libsipp / prism.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-01  |  6.3 KB  |  219 lines

  1. /*
  2.  * File: prism.c 
  3.  *
  4.  * Create a prism from a polygonal cross-section in XY.
  5.  * The points must be given in counter-clockwise order as viewed from
  6.  * the front (+ve Z).
  7.  *
  8.  * Author:  David Jones
  9.  *          djones@awesome.berkeley.edu
  10.  *          11may91 djones
  11.  *
  12.  * Adapted for inclusion into the SIPP package: Inge Wallin
  13.  * Extended with 2D texture support:            Jonas Yngvesson
  14.  */
  15.  
  16. #include <stdio.h>
  17. #include <math.h>
  18.  
  19. #include <sipp.h>
  20. #include <primitives.h>
  21. #include <xalloca.h>
  22.  
  23.  
  24. Object *
  25. sipp_prism(num_points, points, length, surface, shader, texture)
  26.     int          num_points;
  27.     Vector  * points;
  28.     double    length;
  29.     void    * surface;
  30.     Shader  * shader;
  31.     int       texture;
  32. {
  33.     Object  * prism;
  34.     double  * u;
  35.     double  * v;
  36.     int          i;
  37.     int          j;
  38.  
  39.     switch (texture) {
  40.       case NATURAL:
  41.         u = (double *)alloca((num_points + 1) * sizeof(double));
  42.         u[0] = 0.0;
  43.         for (i = 1; i <= num_points; i++) {
  44.             u[i] = u[i - 1] + sqrt(((points[i % num_points].x 
  45.                                      - points[i - 1].x) 
  46.                                     * (points[i % num_points].x 
  47.                                        - points[i - 1].x))
  48.                                    + ((points[i % num_points].y 
  49.                                        - points[i - 1].y) 
  50.                                       * (points[i % num_points].y 
  51.                                          - points[i - 1].y)));
  52.         }
  53.         for (i = 0; i <= num_points; i++) {
  54.             u[i] /= u[num_points];
  55.         }
  56.         break;
  57.  
  58.       case SPHERICAL:
  59.         v = (double *)alloca((num_points + 1) * sizeof(double));
  60.         for (i = 0; i < num_points; i++) {
  61.             v[i] = (atan(length / 2.0
  62.                          / sqrt(points[i].x * points[i].x 
  63.                                 + points[i].y * points[i].y))
  64.                     / M_PI + 0.5);
  65.         }
  66.         v[i] = v[0];
  67.  
  68.       case CYLINDRICAL:    /* Fall trough */
  69.         u = (double *)alloca((num_points + 1) * sizeof(double));
  70.         u[0] = atan2(points[0].y, points[0].x);
  71.         for (i = 1; i < num_points; i++) {
  72.             u[i] = atan2(points[i].y, points[i].x) - u[0];
  73.             if (u[i] < 0.0) {
  74.                 u[i] += 2.0 * M_PI;
  75.             }
  76.             u[i] /= (2.0 * M_PI);
  77.         }
  78.         u[0] = 0.0;
  79.         u[i] = 1.0;
  80.         break;
  81.  
  82.       case WORLD:
  83.       default:
  84.         break;
  85.     }
  86.  
  87.     prism = object_create();
  88.  
  89.     /* The top. */
  90.     for (i = 0; i < num_points ; ++i) {
  91.         switch (texture) {
  92.           case NATURAL:
  93.           case CYLINDRICAL:
  94.           case SPHERICAL:
  95.             vertex_tx_push(points[i].x, points[i].y, length / 2.0, 
  96.                            0.0, 1.0, 0.0);
  97.             break;
  98.  
  99.           case WORLD:
  100.           default:
  101.             vertex_tx_push(points[i].x, points[i].y, length / 2.0, 
  102.                            points[i].x, points[i].y, length / 2.0);
  103.             break;
  104.         }
  105.     }
  106.     polygon_push();
  107.     object_add_surface(prism, surface_create(surface, shader) );
  108.  
  109.     /* The bottom */
  110.     for (i = num_points - 1; i >= 0 ; --i) {
  111.         switch (texture) {
  112.           case NATURAL:
  113.           case CYLINDRICAL:
  114.           case SPHERICAL:
  115.             vertex_tx_push(points[i].x, points[i].y, -length / 2.0, 
  116.                            0.0, 0.0, 0.0);
  117.             break;
  118.  
  119.           case WORLD:
  120.           default:
  121.             vertex_tx_push(points[i].x, points[i].y, -length / 2.0, 
  122.                            points[i].x, points[i].y, -length / 2.0);
  123.             break;
  124.         }
  125.     }
  126.     polygon_push();
  127.     object_add_surface(prism, surface_create(surface, shader) );
  128.  
  129.     /* The sides */
  130.     for (i = 0; i < num_points ; ++i) {
  131.         j = i + 1;
  132.         if (j == num_points)
  133.             j=0;
  134.         switch (texture) {
  135.           case NATURAL:
  136.           case CYLINDRICAL:
  137.             vertex_tx_push(points[i].x, points[i].y,  length / 2.0, 
  138.                            u[i], 1.0, 0.0);
  139.             vertex_tx_push(points[i].x, points[i].y, -length / 2.0, 
  140.                            u[i], 0.0, 0.0);
  141.             vertex_tx_push(points[j].x, points[j].y, -length / 2.0, 
  142.                            u[i + 1], 0.0, 0.0);
  143.             vertex_tx_push(points[j].x, points[j].y,  length / 2.0, 
  144.                            u[i + 1], 1.0, 0.0);
  145.             break;
  146.  
  147.           case SPHERICAL:
  148.             vertex_tx_push(points[i].x, points[i].y,  length / 2.0, 
  149.                            u[i], v[i], 0.0);
  150.             vertex_tx_push(points[i].x, points[i].y, -length / 2.0, 
  151.                            u[i], 1.0 - v[i], 0.0);
  152.             vertex_tx_push(points[j].x, points[j].y, -length / 2.0, 
  153.                            u[i + 1], 1.0 - v[i + 1], 0.0);
  154.             vertex_tx_push(points[j].x, points[j].y,  length / 2.0, 
  155.                            u[i + 1], v[i + 1], 0.0);
  156.             break;
  157.  
  158.           case WORLD:
  159.           default:
  160.             vertex_tx_push(points[i].x, points[i].y,  length / 2.0, 
  161.                            points[i].x, points[i].y,  length / 2.0);
  162.             vertex_tx_push(points[i].x, points[i].y, -length / 2.0, 
  163.                            points[i].x, points[i].y, -length / 2.0);
  164.             vertex_tx_push(points[j].x, points[j].y, -length / 2.0, 
  165.                            points[j].x, points[j].y, -length / 2.0);
  166.             vertex_tx_push(points[j].x, points[j].y,  length / 2.0, 
  167.                            points[j].x, points[j].y,  length / 2.0);
  168.             break;
  169.         }
  170.         polygon_push();
  171.         object_add_surface(prism, surface_create(surface, shader) );
  172.     }
  173.     
  174.     return prism;
  175. }
  176.  
  177.  
  178.  
  179. /*
  180.  * A square block. Generated as a prism.
  181.  */
  182. Object *
  183. sipp_block(xsize, ysize, zsize, surface, shader, texture)
  184.     double    xsize;
  185.     double    ysize;
  186.     double    zsize;
  187.     void    * surface;
  188.     Shader  * shader;
  189.     int       texture;
  190. {
  191.     Vector coor[4];
  192.  
  193.     xsize /= 2.0;
  194.     ysize /= 2.0;
  195.  
  196.     coor[0].x =  xsize; coor[0].y = -ysize;
  197.     coor[1].x =  xsize; coor[1].y =  ysize;
  198.     coor[2].x = -xsize; coor[2].y =  ysize;
  199.     coor[3].x = -xsize; coor[3].y = -ysize;
  200.  
  201.     return sipp_prism(4, coor, zsize, surface, shader, texture);
  202. }
  203.  
  204.  
  205.  
  206. /*
  207.  * A cube.
  208.  */
  209. Object *
  210. sipp_cube(size, surface, shader, texture)
  211.     double    size;
  212.     void    * surface;
  213.     Shader  * shader;
  214.     int       texture;
  215. {
  216.     return sipp_block(size, size, size, surface, shader, texture);
  217. }
  218.  
  219.